# !/usr/bin/env python
# Created by "Thieu" at 11:35, 11/07/2021 ----------%
#       Email: nguyenthieu2102@gmail.com            %
#       Github: https://github.com/thieu1995        %
# --------------------------------------------------%

from mealpy.evolutionary_based.GA import BaseGA
from mealpy.utils.visualize import *
from numpy import sum, mean, sqrt


## Define your own fitness function
# Multi-objective but single fitness/target value. By using weighting method to convert from multiple objectives to single target

def fitness_function(solution):
    f1 = (sum(solution ** 2) - mean(solution)) / len(solution)
    f2 = sum(sqrt(abs(solution)))
    f3 = sum(mean(solution ** 2) - solution)
    return [f1, f2, f3]


problem = {
    "fit_func": fitness_function,
    "lb": [-10, -5, -15, -20, -10, -15, -10, -30],
    "ub": [10, 5, 15, 20, 50, 30, 100, 85],
    "minmax": "min",
    "obj_weights": [0.2, 0.5, 0.3]
}

## Run the algorithm
model = BaseGA(problem, epoch=100, pop_size=50)
best_position, best_fitness = model.solve()
print(f"Best solution: {best_position}, Best fitness: {best_fitness}")

## On the exploration and exploitation in popular swarm-based metaheuristic algorithms (the idea come from this paper)

# This exploration/exploitation chart should draws for single algorithm and single fitness function
export_explore_exploit_chart([model.history.list_exploration, model.history.list_exploitation])  # Draw exploration and exploitation chart

# Parameter for this function
# data: is the list of array
#       + optimizer.history_list_explore -> List of exploration percentages
#       + optimizer.history_list_exploit -> List of exploitation percentages
# title: title of the figure
# list_legends: list of line's name, default = ("Exploration %", "Exploitation %")
# list_styles: matplotlib API, default = ('-', '-')
# list_colors: matplotlib API, default = ('blue', 'orange')
# x_label: string, default = "#Iteration"
# y_label: string, default = "Percentage"
# filename: string, default = "explore_exploit_chart"
# exts: matplotlib API, default = (".png", ".pdf") --> save figure in format of png and pdf
# verbose: show the figure on Python IDE, default = True


# This diversity chart should draws for multiple algorithms for a single fitness function at the same time to compare the diversity spreading
export_diversity_chart([model.history.list_diversity], list_legends=['GA'])  # Draw diversity measurement chart


# Parameter for this function
# data: is the list of array
#       + optimizer1.history_list_div -> List of diversity spreading for this optimizer1
#       + optimizer2.history_list_div -> List of diversity spreading for this optimizer1
# title: title of the figure
# list_legends: list, e.g. ("GA", "PSO",..)
# list_styles: matplotlib API, default = None
# list_colors: matplotlib API, default = None
# x_label: string, default = "#Iteration"
# y_label: string, default = "Diversity Measurement"
# filename: string, default = "diversity_chart"
# exts: matplotlib API, default = (".png", ".pdf") --> save figure in format of png and pdf
# verbose: show the figure on Python IDE, default = True
